package com.qujia.station.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qujia.common.constant.UserConstants;
import com.qujia.common.core.domain.AjaxResult;
import com.qujia.common.core.domain.entity.SysUser;
import com.qujia.common.exception.BaseException;
import com.qujia.common.utils.SecurityUtils;
import com.qujia.station.domain.Commodity;
import com.qujia.station.domain.OutboundRecords;
import com.qujia.station.domain.StorageRecords;
import com.qujia.station.domain.StorageRecordsDetails;
import com.qujia.station.domain.dto.StorageRecordsDetailsDto;
import com.qujia.station.domain.dto.StorageRecordsDetailsUpdateDto;
import com.qujia.station.domain.dto.StorageRecordsQueryDto;
import com.qujia.station.domain.dto.StorageRecordsUpdateDto;
import com.qujia.station.domain.vo.StorageRecordsVo;
import com.qujia.station.enums.StorageStatusEnum;
import com.qujia.station.mapper.CommodityMapper;
import com.qujia.station.mapper.StorageRecordsMapper;
import com.qujia.station.service.OutboundRecordsService;
import com.qujia.station.service.StorageRecordsDetailsService;
import com.qujia.station.service.StorageRecordsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

@Service
@Slf4j
public class StorageRecordsServiceImpl extends ServiceImpl<StorageRecordsMapper, StorageRecords> implements StorageRecordsService {

    @Autowired
    private StorageRecordsDetailsService storageRecordsDetailsService;
    @Autowired
    private OutboundRecordsService outboundRecordsService;
    @Autowired
    private CommodityMapper commodityMapper;

    @Override
    public StorageRecordsVo selectStorageRecordsDetails(Long storageRecordsId) {
        log.info("入库详情入参：{}",storageRecordsId);
        StorageRecords storageRecords = getById(storageRecordsId);
        StorageRecordsVo storageRecordsVo = BeanUtil.copyProperties(storageRecords, StorageRecordsVo.class);
        LambdaQueryWrapper<StorageRecordsDetails> wrapper = new LambdaQueryWrapper();
        wrapper.eq(StorageRecordsDetails::getStorageRecordsId,storageRecords.getStorageRecordsId());
        List<StorageRecordsDetails> list = storageRecordsDetailsService.list(wrapper);
        if(CollectionUtil.isNotEmpty(list)){
            List<StorageRecordsDetailsDto> storageRecordsDetailsDtos = BeanUtil.copyToList(list, StorageRecordsDetailsDto.class);
            storageRecordsVo.setStorageRecordsDetailsDtoList(storageRecordsDetailsDtos);
        }
        return storageRecordsVo;
    }

    @Override
    public PageInfo<StorageRecordsVo> selectStorageRecordsList(StorageRecordsQueryDto storageRecordsQueryDto) {
        log.info("入库列表入参：{}", JSONObject.toJSONString(storageRecordsQueryDto));
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if(null==user){
            throw new BaseException("当前用户不存在");
        }
        if(UserConstants.LEVEL_TWO.equals(user.getUserLevel())){
            storageRecordsQueryDto.setEnterpriseId(user.getEnterpriseId());
        }else if(UserConstants.LEVEL_THREE.equals(user.getUserLevel())){
            storageRecordsQueryDto.setStationId(user.getStationId());
        }
        PageHelper.startPage(storageRecordsQueryDto.getPageNum(),storageRecordsQueryDto.getPageSize());
        List<StorageRecordsVo> storageRecordsVos = baseMapper.selectStorageRecordsList(storageRecordsQueryDto);
        PageInfo<StorageRecordsVo> pageInfo = new PageInfo<>(storageRecordsVos);
        if(CollectionUtil.isNotEmpty(storageRecordsVos)){
            storageRecordsVos.forEach(x->{
                x.setStatusDesc(StorageStatusEnum.getMsg(x.getStatus()));
            });
            pageInfo.setList(storageRecordsVos);
        }else {
            pageInfo.setList(new ArrayList<>());
        }
        return pageInfo;
    }
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public AjaxResult updateStorageRecords(StorageRecordsUpdateDto storageRecordsUpdateDto) {
        log.info("调拨入库修改入参：{}", JSONObject.toJSONString(storageRecordsUpdateDto));
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if(null==user){
            throw new BaseException("当前用户不存在");
        }
        if(CollectionUtil.isNotEmpty(storageRecordsUpdateDto.getStorageRecordsUpdateDtoList())){
            AtomicLong atomicLong = new AtomicLong(0);
            for (StorageRecordsDetailsUpdateDto storageRecordsDetailsUpdateDto : storageRecordsUpdateDto.getStorageRecordsUpdateDtoList()) {
                if(storageRecordsDetailsUpdateDto.getInventoryQuantity().compareTo(storageRecordsDetailsUpdateDto.getInventoryOutQuantity())>0){
                    throw new BaseException("调拨数量不能大于出库数量");
                }
                storageRecordsDetailsService.lambdaUpdate().
                         eq(StorageRecordsDetails::getStorageDetailsId, storageRecordsDetailsUpdateDto.getStorageDetailsId())
                        .set(StorageRecordsDetails::getInventoryQuantity, storageRecordsDetailsUpdateDto.getInventoryQuantity())
                        .set(StorageRecordsDetails::getUpdateTime,new Date())
                        .set(StorageRecordsDetails::getUpdateUser,user.getUserName())
                        .update();
                atomicLong.getAndAdd(storageRecordsDetailsUpdateDto.getInventoryQuantity());
            }
            //入库商品总数回写到入库记录表
            lambdaUpdate().eq(StorageRecords::getStorageRecordsId,storageRecordsUpdateDto.getStorageRecordsId())
                    .set(StorageRecords::getStorageCommodityNum,atomicLong.get())
                    .set(StorageRecords::getOperatorId,user.getUserId())
                    .set(StorageRecords::getOperatorName,user.getUserName())
                    .set(StorageRecords::getUpdateUser,user.getUserId())
                    .set(StorageRecords::getUpdateUserName,user.getUserName())
                    .update();
        }
        return AjaxResult.success();
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public AjaxResult confirmStorage(StorageRecordsUpdateDto storageRecordsUpdateDto) {
        log.info("确认入库入参：{}", JSONObject.toJSONString(storageRecordsUpdateDto));
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if(null==user){
            throw new BaseException("当前用户不存在");
        }
        if(CollectionUtil.isNotEmpty(storageRecordsUpdateDto.getStorageRecordsUpdateDtoList())){
            AtomicLong atomicLong = new AtomicLong(0);
            for (StorageRecordsDetailsUpdateDto storageRecordsDetailsUpdateDto : storageRecordsUpdateDto.getStorageRecordsUpdateDtoList()) {
                if(storageRecordsDetailsUpdateDto.getInventoryQuantity().compareTo(storageRecordsDetailsUpdateDto.getInventoryOutQuantity())>0){
                    throw new BaseException("调拨数量不能大于出库数量");
                }
                storageRecordsDetailsService.lambdaUpdate().
                        eq(StorageRecordsDetails::getStorageDetailsId, storageRecordsDetailsUpdateDto.getStorageDetailsId())
                        .set(StorageRecordsDetails::getInventoryQuantity, storageRecordsDetailsUpdateDto.getInventoryQuantity())
                        .set(StorageRecordsDetails::getUpdateTime,new Date())
                        .set(StorageRecordsDetails::getUpdateUser,user.getUserName())
                        .update();
                atomicLong.getAndAdd(storageRecordsDetailsUpdateDto.getInventoryQuantity());
                //查询油站对应的商品信息并且加上调入数量
                Commodity commodity = new Commodity();
                commodity.setBarCode(storageRecordsDetailsUpdateDto.getBarCode());
                commodity.setStationId(storageRecordsUpdateDto.getStorageStationId());
                Commodity commodity1 = commodityMapper.selectCommodity(commodity);
                if(null==commodity1){
                    throw new BaseException("入库商品信息不存在，条码为："+storageRecordsDetailsUpdateDto.getBarCode());
                }
                log.info("查询对应的商品信息：{}",JSONObject.toJSONString(commodity1));
                long totalSum = commodity1.getInventory() + storageRecordsDetailsUpdateDto.getInventoryQuantity();
                log.info("计算总库存数量：{}",totalSum);
                commodity1.setInventory(totalSum);
                commodityMapper.update(commodity1);
            }
            //入库商品总数回写到入库记录表
            lambdaUpdate().eq(StorageRecords::getStorageRecordsId,storageRecordsUpdateDto.getStorageRecordsId())
                    .set(StorageRecords::getStorageCommodityNum,atomicLong.get())
                    .set(StorageRecords::getStatus,StorageStatusEnum.STORAGE.getCode())
                    .set(StorageRecords::getUpdateUser,user.getUserId())
                    .set(StorageRecords::getUpdateUserName,user.getUserName())
                    .set(StorageRecords::getStorageRepositoryTime,new Date())
                    .set(StorageRecords::getOperatorId,user.getUserId())
                    .set(StorageRecords::getOperatorName,user.getUserName())
                    .update();
        }

        //同步出库
        outboundRecordsService.lambdaUpdate().eq(OutboundRecords::getRecordsCode,storageRecordsUpdateDto.getRecordsCode())
                .set(OutboundRecords::getStatus,StorageStatusEnum.STORAGE.getCode())
                .set(OutboundRecords::getUpdateUser,user.getUserId())
                .set(OutboundRecords::getUpdateUserName,user.getUserName())
                .set(OutboundRecords::getOutboundRepositoryTime,new Date())
                .update();
        return AjaxResult.success();
    }
}
